/**
 *    @file       asynqueue.h
 *
 *    @brief      
 *    @details
 *
 *    @version    1.0
 *    @date       12/13/2012 05:06:26 PM
 *
 *    @author     Theophilus, wangtf418@gmail.com
 */
#ifndef _BF_ASYBQUEUE_H_
#define _BF_ASYBQUEUE_H_

#include <pthread.h>
#include <deque>

template<typename _Telem>
class asynqueue
{
public:
	asynqueue()
	{
		pthread_mutex_init(&m_mutex_lock, NULL);
	}

	~asynqueue()
	{
		pthread_mutex_destroy(&m_mutex_lock);
	}

public:
	void put(_Telem *elem)
	{
		pthread_mutex_lock(&m_mutex_lock);
		m_queue.push_back(elem);
		pthread_mutex_unlock(&m_mutex_lock);
	}

	void put(_Telem *elem, bf_int_t ifpri)
	{
		pthread_mutex_lock(&m_mutex_lock);
		if (ifpri)
		{
			m_queue.push_front(elem);
		}
		else
		{
			m_queue.push_back(elem);
		}
		pthread_mutex_unlock(&m_mutex_lock);
	}
	
	_Telem* get()
	{
		_Telem *elem = NULL;
		pthread_mutex_lock(&m_mutex_lock);
		if (m_queue.begin() != m_queue.end())
		{
			elem = m_queue.front();
			m_queue.pop_front();
		}
		pthread_mutex_unlock(&m_mutex_lock);
		return elem;
	}

	bf_size_t size()
	{
		bf_size_t queue_size = 0;
		pthread_mutex_lock(&m_mutex_lock);
		queue_size = m_queue.size();
		pthread_mutex_unlock(&m_mutex_lock);
		return queue_size;
	}
private:
	std::deque<_Telem*> m_queue;
	pthread_mutex_t m_mutex_lock;
};

#endif

